/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package com.ristolaakso.neuroopt2;

import common.statistics.Series;
import java.util.logging.Level;
import java.util.logging.Logger;
import neuron.Network;
import neuron.NetworkStatistics;

/**
 *
 * @author Risto Laakso <risto.laakso@gmail.com>
 */
public class FeatureVector {
// branches, asym, is len, turn angle, branch angle, scholl

	private static int SCHOLL = 20;
	double feat[] = new double[5+SCHOLL];
	double w[] = new double[feat.length];

	public FeatureVector() {
		w[0] = 0.2;
		w[1] = 10.0;
		w[2] = 0.1;
		w[3] = 1.0;
		w[4] = 1.0;
		for (int i = 0; i < 20; i++) {
			w[i+5] = 1./20;
		}
	}

	public boolean hasNAN()
	{
		for (double d : feat) {
			if (Double.isNaN(d) || Double.isInfinite(d)) {
				return true;
			}
		}
		return false;
	}

	public FeatureVector(double[] feat) {
		this();
		this.feat = feat;
	}

	public FeatureVector(Network data) {
		this();

		NetworkStatistics ns = new NetworkStatistics(data);

		feat[0] = ns.basalTermSegCountDist().mean();
	
		feat[1] = ns.basalAsymIndexDist().mean();

		feat[2] = ns.basalIntSegLenDist().mean();
	
		feat[3] = ns.basalTurningAngles().mean();

		feat[4] = ns.basalBranchingAngles().mean();

		Logger.getLogger("com.ristolaakso").logp(Level.INFO, Thread.currentThread().getStackTrace()[0].getClassName(), Thread.currentThread().getStackTrace()[0].getMethodName(), "N=%d", data.size());

		Series[] sholl = ns.basalSholl();
		for (int i = 0; i < 20; i++) {
			feat[i+5] = sholl[i].mean();
		}
		String msg = "";
		for (int i = 0; i < feat.length; i++) {
			msg += feat[i] + ", ";
		}
		Logger.getLogger("com.ristolaakso").logp(Level.INFO, Thread.currentThread().getStackTrace()[0].getClassName(), Thread.currentThread().getStackTrace()[0].getMethodName(), msg);
	}



	@Override
	public String toString() {
		return String.format("[%f, %f, %f, %f, %f, ..]", feat[0], feat[1], feat[2], feat[3], feat[4]);
	}

	/**
	 * Mean square weighted distance to vector b
	 * @param b
	 * @return
	 */
	public double distanceN2(FeatureVector b)
	{
		double sum = 0;
		for (int i = 0; i < feat.length; i++) {
			double diff = b.feat[i] - feat[i];
			diff *= diff;
			sum += w[i] * diff;
		}
		return Math.sqrt(sum);
	}

}
